package com.zbld.demo;

import org.apache.poi.xwpf.usermodel.*;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * @author zl
 * @version 1.0
 * @description: TODO
 * @date 2022/2/25 10:53
 */
public class TestDemo {
        
        public static void main(String[] args) {
    
            //返回新旧文本的html的map对象
            HashMap<String, String> map = new HashMap<String, String>();
            
            //获取文件保存路径
            String oldUrl="C:/Users/12855/Desktop/1.docx";
            String newUrl="C:/Users/12855/Desktop/2.docx";
    
    
            //原始文件内容
            StringBuilder oldText = null;
            //最新文件内容
            StringBuilder newText = null;
    
            try {
                //获取文档内容
                oldText= getDocText(oldUrl);
    
                newText= getDocText(newUrl);
            } catch (IOException e) {
                e.printStackTrace();
            }
    
    
            // 随机生成字符串
            String strOne = oldText.toString();
            String strTwo = newText.toString();
    
            //遍历查询到的文档名字
            ArrayList<DiffObject> demotes = new ArrayList<DiffObject>();
    
            while (true) {
                //获取最长公共子串
                String same = maxUtil2(strOne, strTwo).toString();
    
                if (same.length() <= 0) {
                    break;
                }
    
                demotes.add(new DiffObject(same,strTwo.indexOf(same)));
    
                strOne= strOne.replace(same,"-");
                strTwo= strTwo.replace(same,"*");
    
            }
    
            String div="<span style=\"background-color: yellow\">"+newText.toString()+"</span>";
    
            for (DiffObject demote : demotes) {
                div= div.replace(demote.getName(),"<span style=\"background-color: white\">"+demote.getName()+"</span>");
            }
    
            map.put("oldHtml",oldText.toString());
            map.put("newHtml",div);
    
            System.out.println(map.get("oldHtml"));
            System.out.println(map.get("newHtml"));
        }

    /**
     * 获取文档内容
     * @param path 文档磁盘路径
     * @throws IOException
     */
    private static StringBuilder getDocText(String path ) throws IOException {
        StringBuilder builder= new StringBuilder();
        XWPFDocument doc = new XWPFDocument(new FileInputStream(path));

        List<IBodyElement> elements = doc.getBodyElements();
        for (IBodyElement element : elements) {
            // 段落
            if (element instanceof XWPFParagraph) {
                XWPFParagraph paragraph = (XWPFParagraph) element;

                List<XWPFRun> runs = paragraph.getRuns();
                //空行用标签换行
                if (runs.size() == 0) {
                    builder.append("<br>");
                }
                for (XWPFRun run : runs) {
                    builder.append(run.text());
                }
            }// 表格
            else if (element instanceof XWPFTable) {
                XWPFTable table= (XWPFTable) element;

                // 获取每个单元格
                List<XWPFTableRow> rows = table.getRows();

                for (XWPFTableRow row : rows) {
                    List<XWPFTableCell> cells = row.getTableCells();
                    for (XWPFTableCell cell : cells) {
                        // 一个单元格可以理解为一个word文档，单元格里也可以加段落与表格
                        List<XWPFParagraph> paragraphs = cell.getParagraphs();
                        for (XWPFParagraph paragraph : paragraphs) {
                            List<XWPFRun> runs = paragraph.getRuns();
                            //空单元格用空格代替
                            if (runs.size() == 0) {
                                builder.append(" ");
                            }
                            for (XWPFRun run : runs) {
                                builder.append(run.text()+" ");
                            }
                        }
                    }
                    //每行加个换行标签
                    builder.append("<br>");
                }
            }
        }

        return builder;

    }

    /**
     * 查找最长公共子串
     * @param str1
     * @param str2
     * @return
     */
    private static StringBuilder maxUtil2(String str1, String str2) {
        //把字符串转成字符数组
        char[] arr1 = str1.toCharArray();
        char[] arr2 = str2.toCharArray();
        // 把两个字符串分别以行和列组成一个二维矩阵
        int[][] temp = new int[arr1.length][arr2.length];
        // 存储最长公共子串长度
        int length = 0;
        //start表明最长公共子串的起始点，end表明最长公共子串的终止点
        int end = 0;
        int start = 0;
        ////初始化二维矩阵中的第一行
        for (int i = 0; i < arr2.length; i++) {
            temp[0][i] = (arr1[0] == arr2[i]) ? 1 : 0;
        }
        //初始化二维矩阵中的第一列
        for (int j = 0; j < arr1.length; j++) {
            temp[j][0] = (arr2[0] == arr1[j]) ? 1 : 0;
        }
        //嵌套for循环：比较二维矩阵中每个点对应行列字符中否相等，相等的话值设置为1，否则设置为0
        for (int i = 1; i < arr1.length; i++) {
            for (int j = 1; j < arr2.length; j++) {
                if (arr1[i] == arr2[j]) {
                    temp[i][j] = temp[i - 1][j - 1] + 1;

                    if (temp[i][j] > length) {
                        length = temp[i][j];
                        end = j;
                    }
                } else
                    temp[i][j] = 0;

            }
        }
        //求出最长公共子串的起始点
        start=end-length+1;
        StringBuilder sb=new StringBuilder();
        //通过查找出值为1的最长对角线就能找到最长公共子串
        for (int j = start; j < end+1; j++) {
            sb.append(arr2[j]);
        }

        return sb;
    }
    
}
